﻿using IR.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IR.Model.Models
{
    public class MUser
    {
        private string _username;
        private string _fname;
        private string _lname;
        private string _email;
        private string _password;

        #region ***Properties***
        public string Username
        {
            get { return _username; }
            set
            {
                if (value != null)
                    _username = value;
            }
        }

        public string FName
        {
            get { return _fname; }
            set
            {
                if (value != null)
                    _fname = value;
            }
        }

        public string LName
        {
            get { return _lname; }
            set
            {
                if (value != null)
                    _lname = value;
            }
        }

        public string Email
        {
            get { return _email; }
            set
            {
                if (value != null)
                    _email = value;
            }
        }

        public string Password
        {
            get { return _password; }
            set
            {
                if (value != null)
                    _password = value;
            }
        }
        #endregion

        /// <summary>
        /// This will save the current user (new or old)
        /// </summary>
        /// <param name="allowOverwrite">Allow updating old users</param>
        /// <returns>True if saved</returns>
        public bool Save(bool allowOverwrite = false)
        {
            IREntities context = new IREntities();

            // Set values as these are needed either way
            user currentUser = new user
            {
                username = _username,
                fname = _fname,
                lname = _lname,
                email = _email,
                password = _password
            };

            // Check if new user
            user original = context.users.Find(_username);

            if (original == null)
            {
                try
                {
                    context.users.Add(currentUser);
                    context.SaveChanges();
                    return true;
                }
                catch
                {
                    return false;
                }
            }
            else if (allowOverwrite == true)
            {
                try
                {
                    context.Entry(original).CurrentValues.SetValues(currentUser);
                    context.SaveChanges();
                    return true;
                }
                catch
                {
                    return false;
                }
            }

            return false;
        }

        /// <summary>
        /// Loads and returns a user (Can be used to initialize)
        /// </summary>
        /// <param name="usernameToLoad">Username to look for</param>
        /// <returns>Null if failed</returns>
        public static MUser Load(string usernameToLoad)
        {
            IREntities context = new IREntities();

            // Search for the user
            user original = context.users.Find(usernameToLoad);

            // If found load it
            if (original == null)
            {
                return null;
            }
            else
            {
                MUser currentUser = new MUser();

                currentUser._username = original.username;
                currentUser._fname = original.fname;
                currentUser._lname = original.lname;
                currentUser._email = original.email;
                currentUser._password = original.password;

                return currentUser;
            }
        }

        /// <summary>
        /// Gets all ideas currently in the DB
        /// </summary>
        /// <returns>List of all users</returns>
        private static List<MUser> GetAllUsers()
        {
            IREntities context = new IREntities();

            List<user> rowList = context.users.Select(v => v).ToList();
            List<MUser> returnList = new List<MUser>(10);

            foreach (user row in rowList)
            {
                MUser currentUser = new MUser();

                currentUser._username = row.username;
                currentUser._fname = row.fname;
                currentUser._lname = row.lname;
                currentUser._email = row.email;
                currentUser._password = row.password;

                returnList.Add(currentUser);
            }

            return returnList;
        }

        /// <summary>
        /// Runs a query on the version table based on a Dictionary you pass in
        /// </summary>
        /// <param name="queries">Dictonary... key = column name, value = value in column</param>
        /// <returns>List of MIdea matching all params, all if null param</returns>
        public static List<MUser> QueryUsers(Dictionary<string, object> queries)
        {
            IREntities context = new IREntities();

            var listOfProperties = typeof(MUser).GetProperties().ToList();

            List<MUser> returnUsers = GetAllUsers();

            foreach (KeyValuePair<string, object> currentQuery in queries)
            {
                // Gets the current property (column) by stripping off the opening part that defines the namespace
                var currentProperty = listOfProperties
                    .Where(p => p.ToString().Split(' ').ElementAtOrDefault(1) == currentQuery.Key).FirstOrDefault();
                // Filters 'in' all rows that have the column value asked for
                //(so if multiple values are asked for it only returns rows with all values asked for)
                returnUsers = returnUsers.Where(v => currentProperty.GetValue(v).ToString() == currentQuery.Value.ToString()).ToList();
            }

            return returnUsers;
        }
    }
}
